﻿#include <QFile>
#include <iostream>
#include <string>
#include <fstream>
#include <assert.h>
#include <QDir>
#include <qDebug>
#include "corecrt_math_defines.h"
#include "DataImportConfigurationData.h"
#include "DialogDataImportConfiguration.h"
#include "BaseModule/QJsonHelper/QJsonSerializer.h"
#include "BaseModule/GlobalHelper.h"
#include "MainWindowSignalHandler.h"
// #include "BaseModule/IBaseSignal.h"

using namespace std;
namespace pst
{
    // <DataImportConfigurationData>
    DataImportConfigurationData::~DataImportConfigurationData()
    {
        if (m_VariableCategoryData.size())
            m_VariableCategoryData.clear();
        if (m_VariableCategoryTotalData.size())
            m_VariableCategoryTotalData.clear();
        if (m_DependentVariableData.size())
            m_DependentVariableData.clear();
        if (m_DependentVariableCategoryData1.size())
            m_DependentVariableCategoryData1.clear();
        if (m_DependentVariableCategoryData2.size())
            m_DependentVariableCategoryData2.clear();
        if (m_DependentVariableCategoryUnitData.size())
            m_DependentVariableCategoryUnitData.clear();
    }
    DataImportConfigurationData* DataImportConfigurationData::_instance = nullptr;

    DataImportConfigurationData* DataImportConfigurationData::getinstance()
    {
        if (_instance == nullptr)
        {
            _instance = new DataImportConfigurationData;
        }
        return _instance;
    }

    void DataImportConfigurationData::initDataImportConfigurationData()
    {
        initeVariableCategoryTotalData();
        initDependentVariableTotalData();
    }

    void DataImportConfigurationData::initeVariableCategoryTotalData()
    {
        QList<QString> _tempUnitList1;
        QPair<QString, QList<QString>> _tempPair1;
        _tempUnitList1.append("Hz");
        _tempUnitList1.append("KHz");
        _tempUnitList1.append("MHz");
        _tempUnitList1.append("GHz");
        _tempPair1.first = QString("频率");
        _tempPair1.second = _tempUnitList1;
        m_VariableCategoryData.append(_tempPair1.first);
        m_VariableCategoryTotalData.append(_tempPair1);

        QList<QString> _tempUnitList2;
        QPair<QString, QList<QString>> _tempPair2;
        _tempUnitList2.append("mm");
        _tempUnitList2.append("cm");
        _tempUnitList2.append("m");
        _tempPair2.first = QString("X坐标");
        _tempPair2.second = _tempUnitList2;
        m_VariableCategoryData.append(_tempPair2.first);
        m_VariableCategoryTotalData.append(_tempPair2);

        QPair<QString, QList<QString>> _tempPair3;
        _tempPair3.first = QString("Y坐标");
        _tempPair3.second = _tempUnitList2;
        m_VariableCategoryData.append(_tempPair3.first);
        m_VariableCategoryTotalData.append(_tempPair3);

        QPair<QString, QList<QString>> _tempPair4;
        _tempPair4.first = QString("Z坐标");
        _tempPair4.second = _tempUnitList2;
        m_VariableCategoryData.append(_tempPair4.first);
        m_VariableCategoryTotalData.append(_tempPair4);

        QPair<QString, QList<QString>> _tempPair5;
        _tempPair5.first = QString("半径rho");
        _tempPair5.second = _tempUnitList2;
        m_VariableCategoryData.append(_tempPair5.first);
        m_VariableCategoryTotalData.append(_tempPair5);

        QPair<QString, QList<QString>> _tempPair6;
        _tempPair6.first = QString("半径r");
        _tempPair6.second = _tempUnitList2;
        m_VariableCategoryData.append(_tempPair6.first);
        m_VariableCategoryTotalData.append(_tempPair6);

        QList<QString> _tempUnitList7;
        QPair<QString, QList<QString>> _tempPair7;
        _tempUnitList7.append("deg");
        _tempPair7.first = QString("Theta");
        _tempPair7.second = _tempUnitList7;
        m_VariableCategoryData.append(_tempPair7.first);
        m_VariableCategoryTotalData.append(_tempPair7);

        QList<QString> _tempUnitList8;
        QPair<QString, QList<QString>> _tempPair8;
        _tempUnitList8.append("deg");
        _tempPair8.first = QString("Phi");
        _tempPair8.second = _tempUnitList8;
        m_VariableCategoryData.append(_tempPair8.first);
        m_VariableCategoryTotalData.append(_tempPair8);

        QList<QString> _tempUnitList9;
        QPair<QString, QList<QString>> _tempPair9;
        _tempUnitList9.append("ns");
        _tempUnitList9.append("us");
        _tempUnitList9.append("ms");
        _tempUnitList9.append("s");
        _tempUnitList9.append("min");
        _tempUnitList9.append("h");
        _tempPair9.first = QString("时间");
        _tempPair9.second = _tempUnitList9;
        m_VariableCategoryData.append(_tempPair9.first);
        m_VariableCategoryTotalData.append(_tempPair9);
    }
    void DataImportConfigurationData::initDependentVariableTotalData()
    {
        QString _DependentVariable1 = QString("因变量（标量）");
        QString _DependentVariable2 = QString("因变量（实部+虚部）");
        QString _DependentVariable3 = QString("因变量（幅度+相位）");
        m_DependentVariableData.append(_DependentVariable1);
        m_DependentVariableData.append(_DependentVariable2);
        m_DependentVariableData.append(_DependentVariable3);

        QString _DependentVariableCategory1 = QString("电场-远场");
        QString _DependentVariableCategory2 = QString("电场-近场");
        QString _DependentVariableCategory3 = QString("电流");
        QString _DependentVariableCategory4 = QString("电压");
        QString _DependentVariableCategory5 = QString("功率");
        QString _DependentVariableCategory6 = QString("人体吸收比");
        QString _DependentVariableCategory7 = QString("增益");
        QString _DependentVariableCategory8 = QString("方向性系数");
        QString _DependentVariableCategory9 = QString("雷达散射截面（RCS）");
        QString _DependentVariableCategory10 = QString("S参数");
        QString _DependentVariableCategory11 = QString("驻波比");
        QString _DependentVariableCategory12 = QString("反射系数");
        QString _DependentVariableCategory13 = QString("磁场-近场");
        m_DependentVariableCategoryData1.append(_DependentVariableCategory1);
        m_DependentVariableCategoryData1.append(_DependentVariableCategory2);
        m_DependentVariableCategoryData1.append(_DependentVariableCategory13);
        m_DependentVariableCategoryData1.append(_DependentVariableCategory3);
        m_DependentVariableCategoryData1.append(_DependentVariableCategory4);
        m_DependentVariableCategoryData1.append(_DependentVariableCategory5);
        m_DependentVariableCategoryData1.append(_DependentVariableCategory6);
        m_DependentVariableCategoryData1.append(_DependentVariableCategory7);
        m_DependentVariableCategoryData1.append(_DependentVariableCategory8);
        m_DependentVariableCategoryData1.append(_DependentVariableCategory9);
        m_DependentVariableCategoryData1.append(_DependentVariableCategory10);
        m_DependentVariableCategoryData1.append(_DependentVariableCategory11);
        m_DependentVariableCategoryData1.append(_DependentVariableCategory12);

        m_DependentVariableCategoryData2.append(_DependentVariableCategory1);
        m_DependentVariableCategoryData2.append(_DependentVariableCategory2);
        m_DependentVariableCategoryData2.append(_DependentVariableCategory13);
        m_DependentVariableCategoryData2.append(_DependentVariableCategory3);
        m_DependentVariableCategoryData2.append(_DependentVariableCategory4);
        m_DependentVariableCategoryData2.append(_DependentVariableCategory10);
        m_DependentVariableCategoryData2.append(_DependentVariableCategory12);

        QList<QString> _tempUnitList1;
        _tempUnitList1.append("V");
        _tempUnitList1.append("mV");

        QList<QString> _tempUnitList2;
        _tempUnitList2.append("V/m");

        QList<QString> _tempUnitList3;
        _tempUnitList3.append("A/m");

        QList<QString> _tempUnitList4;
        _tempUnitList4.append("A");
        _tempUnitList4.append("mA");

        QList<QString> _tempUnitList5;
        _tempUnitList5.append("W");
        _tempUnitList5.append("mW");

        QList<QString> _tempUnitList6;
        _tempUnitList6.append("W/Kg");
        _tempUnitList6.append("mW/g");

        QList<QString> _tempUnitList7;
        _tempUnitList7.append("空白");

        m_DependentVariableCategoryUnitData.append({_DependentVariableCategory1, _tempUnitList1});
        m_DependentVariableCategoryUnitData.append({_DependentVariableCategory2, _tempUnitList2});
        m_DependentVariableCategoryUnitData.append({_DependentVariableCategory13, _tempUnitList3});
        m_DependentVariableCategoryUnitData.append({_DependentVariableCategory3, _tempUnitList4});
        m_DependentVariableCategoryUnitData.append({_DependentVariableCategory4, _tempUnitList1});
        m_DependentVariableCategoryUnitData.append({_DependentVariableCategory5, _tempUnitList5});
        m_DependentVariableCategoryUnitData.append({_DependentVariableCategory6, _tempUnitList6});
        m_DependentVariableCategoryUnitData.append({_DependentVariableCategory7, _tempUnitList7});
        m_DependentVariableCategoryUnitData.append({_DependentVariableCategory8, _tempUnitList7});
        m_DependentVariableCategoryUnitData.append({_DependentVariableCategory9, _tempUnitList7});
        m_DependentVariableCategoryUnitData.append({_DependentVariableCategory10, _tempUnitList7});
        m_DependentVariableCategoryUnitData.append({_DependentVariableCategory11, _tempUnitList7});
        m_DependentVariableCategoryUnitData.append({_DependentVariableCategory12, _tempUnitList7});
    }

    QList<QString> DataImportConfigurationData::getVariableCategoryData()
    {
        return m_VariableCategoryData;
    }

    QList<QPair<QString, QList<QString>>> DataImportConfigurationData::getVariableCategoryTotalData()
    {
        return m_VariableCategoryTotalData;
    }

    QList<QString> DataImportConfigurationData::getDependentVariableData()
    {
        return m_DependentVariableData;
    }

    QList<QString> DataImportConfigurationData::getDependentVariableCategoryData1()
    {
        return m_DependentVariableCategoryData1;
    }
    QList<QString> DataImportConfigurationData::getDependentVariableCategoryData2()
    {
        return m_DependentVariableCategoryData2;
    }

    QList<QPair<QString, QList<QString>>> DataImportConfigurationData::getDependentVariableCategoryUnitData()
    {
        return m_DependentVariableCategoryUnitData;
    }

    bool DataImportConfigurationData::executeTextReadAndImport(QString filePath)
    {
        if ((m_tempFilePaths.count() == m_tempDatas.count()) && (m_tempDatas.count() == m_tempResultFileDatas.count()) && (m_tempResultFileDatas.count() == m_tempFileDataTypes.count()))
        {
            // 只判断文件名是否一样
            for (int i = 0; i < m_tempFilePaths.size(); i++)
            {
                if (m_tempFilePaths[i].split('/').last() == filePath.split('/').last())
                {
                    auto _isSuccess = MainWindowSignalHandlerInstance->TextImportDataProcessing(m_tempImportItemID[i], filePath, m_tempDatas[i], m_tempResultFileDatas[i], m_tempFileDataTypes[i]);
                    if (!_isSuccess)
                        return false;
                    m_tempImportItemID.removeAt(i);
                    m_tempFilePaths.removeAt(i);
                    m_tempDatas.removeAt(i);
                    m_tempResultFileDatas.removeAt(i);
                    m_tempFileDataTypes.removeAt(i);
                }
            }
        }
    }

    void DataImportConfigurationData::addImportItemID(int itemID)
    {
        m_importItemID.append(itemID);
    }

    void DataImportConfigurationData::addTextImportData(QString filePath, const QVector<std::tuple<QString, DialogDataImportConfiguration::DataProperty, QVector<double>>>& datas, QVector<QPair<QPointF, int>> resultFileData, FileDataTypes fileDataType)
    {
        m_filePaths.append(filePath);
        m_datas.append(datas);
        m_resultFileDatas.append(resultFileData);
        m_fileDataTypes.append(fileDataType);
    }
    void DataImportConfigurationData::removeTextImportDataByItemID(int ItemID)
    {
        if (m_importItemID.contains(ItemID))
        {
            int index = m_importItemID.indexOf(ItemID);
            m_importItemID.removeAt(index);
            m_filePaths.removeAt(index);
            m_datas.removeAt(index);
            m_resultFileDatas.removeAt(index);
            m_fileDataTypes.removeAt(index);
        }
    }

    QString DataImportConfigurationData::TextAndCsvCustomDataConversionToQString(QString filePath, const QVector<std::tuple<QString, DialogDataImportConfiguration::DataProperty, QVector<double>>>& datas, QVector<QPair<QPointF, int>> resultFileData, FileDataTypes fileDataType)
    {
        auto _dataStr = toString(datas);
        auto _resultFileDataStr = GlobalHelperInstance->convertVectorPairQPointFIntToQString(resultFileData);
        QString _totalCustomDataStr = filePath + "|_|" + _dataStr + "|_|" + _resultFileDataStr + "|_|" + QString::number((int)fileDataType);
        return _totalCustomDataStr;
    }
    bool DataImportConfigurationData::TextAndCsvCustomDataConversionFromQStringAndExecute(QString customData)
    {
        auto _customDataStrList = customData.split("|_|");
        if (_customDataStrList.count() != 4)
            return false;
        QString filePath = _customDataStrList[0];
        auto _dataStr = _customDataStrList[1];
        auto _resultFileDataStr = _customDataStrList[2];
        int _fileDataType = _customDataStrList[3].toInt();
        auto _dataList = fromString(_dataStr);
        auto _resultFileData = GlobalHelperInstance->convertQStringToVectorPairQPointFInt(_resultFileDataStr);
        FileDataTypes _fileDataTypeEnum = (FileDataTypes)_fileDataType;
        return MainWindowSignalHandlerInstance->TextImportDataProcessing(-1, filePath, _dataList, _resultFileData, _fileDataTypeEnum);
    }

    void DataImportConfigurationData::readConfig()
    {
        QString configFilePath = GlobalHelperInstance->getProjectTempFilePath() + "/ProjectTreeImportItemData.json";
        QByteArray _strJson;
        if (GlobalHelperInstance->readFile(configFilePath, _strJson))
        {
            QJsonHelper::QJsonSerializer _jsonSerializer;
            auto _ProjectTreeImportItemData = _jsonSerializer.deserialize<DataManager::DataImportConfigurationDataManager*>(_strJson);
            if (_ProjectTreeImportItemData)
            {
                m_configData = QSharedPointer<DataManager::DataImportConfigurationDataManager>(_ProjectTreeImportItemData);
            }
            auto _importItemIDList = _ProjectTreeImportItemData->getImportItemIDList();
            if (_importItemIDList.isEmpty())
                return;
            m_importItemID = _importItemIDList;
            m_filePaths = _ProjectTreeImportItemData->getFilePathList();
            auto _dataList = _ProjectTreeImportItemData->getDataList();
            for (auto _data : _dataList)
            {
                auto _dataList = fromString(_data);
                m_datas.append(_dataList);
            }

            auto _resultFileDataList = _ProjectTreeImportItemData->getResultFileDataList();
            for (auto _resultFileData : _resultFileDataList)
            {
                auto _resultFileDataList = GlobalHelperInstance->convertQStringToVectorPairQPointFInt(_resultFileData);
                m_resultFileDatas.append(_resultFileDataList);
            }

            auto _fileDataTypeList = _ProjectTreeImportItemData->getFileDataTypeList();
            for (auto _type : _fileDataTypeList)
            {
                m_fileDataTypes.append((FileDataTypes)_type);
            }

        }
        m_tempImportItemID = m_importItemID;
        m_tempFilePaths = m_filePaths;
        m_tempDatas = m_datas;
        m_tempResultFileDatas = m_resultFileDatas;
        m_tempFileDataTypes = m_fileDataTypes;
    }

    void DataImportConfigurationData::writeConfig()
    {
        auto _ProjectTempFilePath = GlobalHelperInstance->getProjectTempFilePath();
        QString configFilePath = _ProjectTempFilePath + "/ProjectTreeImportItemData.json";
        if (!m_configData)
        {
            m_configData = QSharedPointer<DataManager::DataImportConfigurationDataManager>(new DataManager::DataImportConfigurationDataManager());
        }
        else
        {
            m_configData->clear();
        }
        if (m_importItemID.count()>0)
        {
            m_configData->setImportItemIDList(m_importItemID);
            m_configData->setFilePathList(m_filePaths);

            QList<QString> _tempDataList;
            for (auto _data : m_datas)
            {
                auto _dataStr = toString(_data);
                _tempDataList.append(_dataStr);
            }
            m_configData->setDataList(_tempDataList);

            QList<QString> _tempResultFileDataList;
            for (auto _resultFileData : m_resultFileDatas)
            {
                auto _resultFileDataStr = GlobalHelperInstance->convertVectorPairQPointFIntToQString(_resultFileData);
                _tempResultFileDataList.append(_resultFileDataStr);
            }
            m_configData->setResultFileDataList(_tempResultFileDataList);

            QList<int> _tempTypesList;
            for (auto _type : m_fileDataTypes)
            {
                _tempTypesList.append((int)_type);
            }
            m_configData->setFileDataTypeList(_tempTypesList);
        }


        QJsonHelper::QJsonSerializer _jsonSerializer;
        QByteArray bytes = _jsonSerializer.serialize<DataManager::DataImportConfigurationDataManager*>(m_configData.get());
        GlobalHelperInstance->writeFile(configFilePath, bytes);
    }

    void DataImportConfigurationData::resetData()
    {
        m_importItemID.clear();
        m_filePaths.clear();
        m_datas.clear();
        m_resultFileDatas.clear();
        m_fileDataTypes.clear();
    }

    // DataProperty转JSON对象
    QJsonObject DataImportConfigurationData::dataPropertyToJson(const DialogDataImportConfiguration::DataProperty& prop)
    {
        QJsonObject obj;
        obj["index"] = prop.index;
        obj["type"] = prop.type;
        obj["name"] = prop.name;
        obj["category"] = prop.category;
        obj["unit"] = prop.unit;
        obj["dependentVariable"] = prop.dependentVariable;
        obj["dependentVariableType"] = prop.dependentVariableType;
        obj["isAssociation"] = prop.isAssociation;
        obj["skipColumns"] = prop.skipColumns;
        obj["isDB"] = prop.isDB;
        obj["associationColumn"] = prop.associationColumn;
        return obj;
    }

    // JSON对象转DataProperty
    DialogDataImportConfiguration::DataProperty DataImportConfigurationData::jsonToDataProperty(const QJsonObject& obj)
    {
        DialogDataImportConfiguration::DataProperty prop;
        prop.index = obj["index"].toInt();
        prop.type = static_cast<DialogDataImportConfiguration::DataType>(obj["type"].toInt());
        prop.name = obj["name"].toString();
        prop.category = obj["category"].toString();
        prop.unit = obj["unit"].toString();
        prop.dependentVariable = obj["dependentVariable"].toString();
        prop.dependentVariableType = obj["dependentVariableType"].toString();
        prop.isAssociation = obj["isAssociation"].toBool();
        prop.skipColumns = obj["skipColumns"].toInt();
        prop.isDB = obj["isDB"].toBool();
        prop.associationColumn = obj["associationColumn"].toInt();
        return prop;
    }

    // 转换为字符串
    QString DataImportConfigurationData::toString(const QVector<std::tuple<QString, DialogDataImportConfiguration::DataProperty, QVector<double>>>& data)
    {
        QJsonArray mainArray;

        // 遍历向量中的每个元素
        for (const auto& tupleItem : data)
        {
            QJsonObject itemObj;

            // 第一个元素：QString
            itemObj["stringValue"] = std::get<0>(tupleItem);

            // 第二个元素：DataProperty
            itemObj["dataProperty"] = dataPropertyToJson(std::get<1>(tupleItem));

            // 第三个元素：QVector<double>
            QJsonArray doubleArray;
            for (double d : std::get<2>(tupleItem))
            {
                doubleArray.append(d);
            }
            itemObj["doubleVector"] = doubleArray;

            mainArray.append(itemObj);
        }

        // 转换为JSON文档并返回字符串
        QJsonDocument doc(mainArray);
        return doc.toJson(QJsonDocument::Compact);
    }

    // 从字符串转换回来
    QVector<std::tuple<QString, DialogDataImportConfiguration::DataProperty, QVector<double>>> DataImportConfigurationData::fromString(const QString& str)
    {
        QVector<std::tuple<QString, DialogDataImportConfiguration::DataProperty, QVector<double>>> result;

        // 解析JSON字符串
        QJsonDocument doc = QJsonDocument::fromJson(str.toUtf8());
        if (!doc.isArray())
            return result; // 返回空向量

        QJsonArray mainArray = doc.array();

        // 遍历JSON数组中的每个元素
        for (const QJsonValue& val : mainArray)
        {
            if (!val.isObject())
                continue; // 跳过无效格式

            QJsonObject itemObj = val.toObject();

            // 解析第一个元素：QString
            QString strVal = itemObj["stringValue"].toString();

            // 解析第二个元素：DataProperty
            DialogDataImportConfiguration::DataProperty prop;
            if (itemObj.contains("dataProperty") && itemObj["dataProperty"].isObject())
            {
                prop = jsonToDataProperty(itemObj["dataProperty"].toObject());
            }

            // 解析第三个元素：QVector<double>
            QVector<double> doubleVec;
            if (itemObj.contains("doubleVector") && itemObj["doubleVector"].isArray())
            {
                QJsonArray doubleArray = itemObj["doubleVector"].toArray();
                for (const QJsonValue& dVal : doubleArray)
                {
                    doubleVec.append(dVal.toDouble());
                }
            }

            // 添加到结果向量
            result.append(std::make_tuple(strVal, prop, doubleVec));
        }

        return result;
    }

} // namespace pst
